From 6a9ee8cf218b621ebc3d88e621f32cc3f030e742 Mon Sep 17 00:00:00 2001 From: Keir Fraser Date: Tue, 6 Apr 2010 07:09:35 +0100 Subject: [PATCH] 1GB Page Table Support for HVM Guest 3/3 This patch adds a new field in hvm to indicate 1gb is supported by CPU. In addition, users can turn 1GB feature on/off using a Xen option ("hap_1gb", default is off). Per Tim's suggestion, I also add an assertion check in shadow/common.c file to prevent affecting shadow code. Signed-off-by: Wei Huang Acked-by: Dongxiao Xu Acked-by: Tim Deegan --- xen/arch/x86/hvm/svm/svm.c | 2 ++ xen/arch/x86/hvm/vmx/vmx.c | 2 ++ xen/arch/x86/mm/p2m.c | 10 +++++++--- xen/arch/x86/mm/shadow/common.c | 5 +++++ xen/include/asm-x86/hvm/hvm.h | 4 ++++ 5 files changed, 20 insertions(+), 3 deletions(-) diff --git a/xen/arch/x86/hvm/svm/svm.c b/xen/arch/x86/hvm/svm/svm.c index 8cc636e182..cbd5d79be5 100644 --- a/xen/arch/x86/hvm/svm/svm.c +++ b/xen/arch/x86/hvm/svm/svm.c @@ -884,6 +884,8 @@ void start_svm(struct cpuinfo_x86 *c) cpuid_edx(0x8000000A) : 0); svm_function_table.hap_supported = cpu_has_svm_npt; + svm_function_table.hap_1gb_pgtb = + (CONFIG_PAGING_LEVELS == 4)? !!(cpuid_edx(0x80000001) & 0x04000000):0; hvm_enable(&svm_function_table); } diff --git a/xen/arch/x86/hvm/vmx/vmx.c b/xen/arch/x86/hvm/vmx/vmx.c index d188749273..2c7df5f729 100644 --- a/xen/arch/x86/hvm/vmx/vmx.c +++ b/xen/arch/x86/hvm/vmx/vmx.c @@ -1445,6 +1445,8 @@ void start_vmx(void) if ( cpu_has_vmx_ept ) vmx_function_table.hap_supported = 1; + + vmx_function_table.hap_1gb_pgtb = 0; setup_vmcs_dump(); diff --git a/xen/arch/x86/mm/p2m.c b/xen/arch/x86/mm/p2m.c index bbe7cf94c6..7bb904d395 100644 --- a/xen/arch/x86/mm/p2m.c +++ b/xen/arch/x86/mm/p2m.c @@ -39,6 +39,10 @@ #define P2M_AUDIT 0 #define P2M_DEBUGGING 0 +/* turn on/off 1GB host page table support for hap */ +static int opt_hap_1gb = 0; +boolean_param("hap_1gb", opt_hap_1gb); + /* Printouts */ #define P2M_PRINTK(_f, _a...) \ debugtrace_printk("p2m: %s(): " _f, __func__, ##_a) @@ -1736,9 +1740,9 @@ int set_p2m_entry(struct domain *d, unsigned long gfn, mfn_t mfn, while ( todo ) { if ( is_hvm_domain(d) && paging_mode_hap(d) ) - order = ( (((gfn | mfn_x(mfn) | todo) & ((1ul << 18) - 1)) == 0) ) ? - 18 : - (((gfn | mfn_x(mfn) | todo) & ((1ul << 9) - 1)) == 0) ? 9 : 0; + order = ( (((gfn | mfn_x(mfn) | todo) & ((1ul << 18) - 1)) == 0) && + hvm_funcs.hap_1gb_pgtb && opt_hap_1gb ) ? 18 : + (((gfn | mfn_x(mfn) | todo) & ((1ul << 9) - 1)) == 0) ? 9 : 0; else order = 0; diff --git a/xen/arch/x86/mm/shadow/common.c b/xen/arch/x86/mm/shadow/common.c index 36f92760cf..beac5278f4 100644 --- a/xen/arch/x86/mm/shadow/common.c +++ b/xen/arch/x86/mm/shadow/common.c @@ -3452,6 +3452,11 @@ static void sh_unshadow_for_p2m_change(struct vcpu *v, unsigned long gfn, { struct domain *d = v->domain; + /* The following assertion is to make sure we don't step on 1GB host + * page support of HVM guest. */ + ASSERT(!(level > 2 && (l1e_get_flags(*p) & _PAGE_PRESENT) && + (l1e_get_flags(*p) & _PAGE_PSE))); + /* If we're removing an MFN from the p2m, remove it from the shadows too */ if ( level == 1 ) { diff --git a/xen/include/asm-x86/hvm/hvm.h b/xen/include/asm-x86/hvm/hvm.h index 0ae7e7ea0a..f52a26c2cd 100644 --- a/xen/include/asm-x86/hvm/hvm.h +++ b/xen/include/asm-x86/hvm/hvm.h @@ -69,6 +69,10 @@ struct hvm_function_table { /* Support Hardware-Assisted Paging? */ int hap_supported; + /* Support 1GB Harware-Assisted Paging? */ + int hap_1gb_pgtb; + + /* * Initialise/destroy HVM domain/vcpu resources */ -- 2.30.2